//date:25/10, Modifies/Uses first version done; Follows left at when both parameters are all synonym; Left:Parent,pattern
//date:27/10,Modifies/Uses/Follows done, left FollowStar/Parent/ParentStar/Pattern
//date:29/10,Modifies/Uses/Follows/FollowsStar done, Start matching with other files, left Parent/ParentStar/Pattern
//date:30/10,Modifies/Uses/Follows/FollowsStar matching completed, left Parent/ParentStar/Pattern
#include "QueryEvaluator.h"
#include "TNode.h"
#include "Follows.h"
#include "Modifies.h"
#include "Uses.h"
#include "Parent.h"
#include "type.h"
#include "DefinitionTable.h"
#include "StmtTable.h"
#include "VarConstTable.h"
#include <vector>
#include <string>
//#include <sstream>

using namespace std;

void QueryEvaluator::setQueryTree(TNode n){
	root = n;
}

void QueryEvaluator::evaluate(){
    // algorithm for evaluate(), Assumption: all query is valid if it successfully created query tree and definition table
    // 1. traverse the query tree for each clause
    // 2. determine the type of clause
    // 3. if the clause is ":result"
    // 4. if the clause is ":Modifies"
    // 5. if the clause is ":Uses"
    // 6. if the clause is ":Follows"
    // 7. if the clause is ":Parents"
    // 8. if the clause is ":pattern"
	found=false;
	resultBoolean = false;
    numChild = root.getChild().size();
	rootChildren = root.getChild();
    for(int i=0;i<numChild;i++){
        node = rootChildren.at(i);// horizontally traverse the siblings
        if(node.getType()==RESULT){
            // create 2-D vector to store the result
            // e.g. resultNameList:{"a","b"}
            //      resultList:{<result of a>"1,2,3",<result of b>"2"}
            //      resultFinal:{"1,2","2,2","3,2","2,2");		
	// ############For CS3201, there is only one synonym after SELECT#############
			children = node.getChild();
			r = children.at(0);
			if(DefinitionTable::getType(r.getIndex())==ASSIGN){
				result = StmtTable::getStmtList();
				for(int j=0;j<result.size();j++){
					if(StmtTable::getType(result.at(j))!=ASSIGN){
						result.erase(result.begin()+j);
						j--;
					}
				}
				resultType = "s";
			}
			else if(DefinitionTable::getType(r.getIndex())==STMT){
				result = StmtTable::getStmtList();
				resultType = "s";
			}
			else if(DefinitionTable::getType(r.getIndex())==VAR){
				result = VarConstTable::getVarList();
				resultType = "v";
			}
			else if(r.getType()==BOOLEAN){
				resultBoolean = false;
			}
			else if(DefinitionTable::getType(r.getIndex())==WHILE){
				result = StmtTable::getStmtList();
				for(int j=0;j<result.size();j++){
					if(StmtTable::getType(result.at(j))!=WHILE){
						result.erase(result.begin()+j);
						j--;
					}
				}
				resultType = "s";
			}
			/*
			else if(r.getType()="ifstat"){// not covered in CS3201
			}
			else if(r.getType()="proc"){// not covered in CS3201
			}
			*/
        }
        else if(node.getType()==SUCHTHAT){// current pointer at "suchThat" node
            node = node.getChild().at(0);// current pointer at the child of "suchThat" node, then move the the child of "SUCHTHAT" node
            if(node.getType()==MODIFIESS){
				x = node.getChild().at(0);// x is the first parameter of Modifies(x,y);
				y = node.getChild().at(1);
				if(x.getType()!=SYNONYM){
					if(y.getType()!=SYNONYM){// e.g. SELECT r such that Modifies(1,"a")
						/* if x.getIndex() doesn't work...
						stmtNumberStr = x.getName();
						istringstream iss(stmtNumberStr);
						iss>>stmtNumber;
						if(Modifies::isModified(stmtNumber,y.getIndex())==false){
						*/
						/* if y.getIndex() doesn't work...
						varName = y.getName();
						if(Modifies::isModified(stmtNumebr,VarConstTable::getIndex(varName))==false){
						*/
						if(Modifies::isModified(x.getIndex(),y.getIndex())==false){
                            result.clear();// note: even result is empty, still can run this command without error
                        }
					}
					else{// if y is synonym, then y must be a var type
						if(y.getIndex() == r.getIndex()){//e.g. SELECT r such that Modifies(1,r)
							for(int j=0;j<result.size();j++){
								if(Modifies::isModified(x.getIndex(),result.at(j))==false){
									result.erase(result.begin()+j);
									j--;
								}
							}
						}
						else if(DefinitionTable::getType(y.getIndex())==VAR){//e.g. SELECT r such that Modifies(1,v)
							temp = VarConstTable::getVarList();// in vector<int> form
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Modifies::isModified(x.getIndex(),temp.at(j))==true){
										j=temp.size();
										found=true;
										resultBoolean = true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Modifies(1,_); isn't it same as Modifies(1,v)?
							temp = VarConstTable::getVarList();// in vector<int> form
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Modifies::isModified(x.getIndex(),temp.at(j))==true){
										j=temp.size();
										found=true;
										resultBoolean = true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
					}
				}
				else{
					if(y.getType()!=SYNONYM){//e.g. SELECT r such that Modifies(x,"a")
						if(r.getIndex()==x.getIndex()){//e.g.SELECT r such that Modifies(r,"a");
							for(int j=0;j<result.size();j++){
								if(Modifies::isModified(result.at(j),y.getIndex())==false){
									result.erase(result.begin()+j);
									j--;
								}
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Modifies(a,"a");
							temp = StmtTable::getStmtList();
							for(int j=0;j<temp.size();j++){
								if(StmtTable::getType(temp.at(j))!=ASSIGN){
									temp.erase(temp.begin()+j);
									j--;
								}
							}
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Modifies::isModified(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Modifies(s,"a");
							temp = StmtTable::getStmtList();
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Modifies::isModified(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Modifies(w,"a");
							temp = StmtTable::getStmtList();
							for(int j=0;j<temp.size();j++){
								if(StmtTable::getType(temp.at(j))!=WHILE){
									temp.erase(temp.begin()+j);
									j--;
								}
							}
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Modifies::isModified(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Modifies( _ ,"a"); isn't it same as Modifies(s,"a")
							temp = StmtTable::getStmtList();
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Modifies::isModified(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						/*
						else if(x.getType()=="procedure"){//this one is in CS3202
						}
						else if(x.getType()=="ifstat"){// this one is in CS3202
						}
						*/
					}
					else{
						//e.g. SELECT r such that Modifies(r,v)
						if(r.getIndex()==x.getIndex()){
							for(int j=0;j<result.size();j++){
								if(Modifies::getStmModified(result.at(j)).empty()){
									result.erase(result.begin()+j);
									j--;
								}
							}
						}
						//e.g. SELECT r such that Modifies(x,r)>>>(a,r)/(s,r)/(w,r)/(_,r)
						else if(r.getIndex()==y.getIndex()){
							//e.g. r = {a,b,c}, a = {1,2,4},so check (1,a),(2,a),(3,a)...as long as one of three is true, then keep 'a'
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=ASSIGN){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Modifies::isModified(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){
								temp = StmtTable::getStmtList();
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Modifies::isModified(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=WHILE){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Modifies::isModified(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){
								temp = StmtTable::getStmtList();
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Modifies::isModified(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							/*
							else if(x.getType()=="procudure"){// this one is in CS3202
							}
							else if(x.getType()=="ifstat"){// this one is in CS3202
							}
							*/
						}
						//e.g. SELECT r such that Modifies(x,v)>>>(a,v)/(s,v)/(w,v)/(_,v)
						else{
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=ASSIGN){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Modifies::isModified(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){
								temp = StmtTable::getStmtList();
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Modifies::isModified(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=WHILE){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Modifies::isModified(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){
								temp = StmtTable::getStmtList();
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Modifies::isModified(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							/*
							else if(x.getType()=="procudure"){// this one is in CS3202
							}
							else if(x.getType()=="ifstat"){// this one is in CS3202
							}
							*/
						}
					}
				}
            }
            else if(node.getType()==USESS){
				x = node.getChild().at(0);// x is the first parameter of Uses(x,y);
				y = node.getChild().at(1);
				if(x.getType()!=SYNONYM){
					if(y.getType()!=SYNONYM){// e.g. SELECT r such that Uses(1,"a")
						if(Uses::isUsed(x.getIndex(),y.getIndex())==false){
                            result.clear();// note: even result is empty, still can run this command without error
                        }
					}
					else{// if y is synonym, then y must be a var type
						if(y.getIndex() == r.getIndex()){//e.g. SELECT r such that Uses(1,r)
							for(int j=0;j<result.size();j++){
								if(Uses::isUsed(x.getIndex(),result.at(j))==false){
									result.erase(result.begin()+j);
									j--;
								}
							}
						}
						else if(DefinitionTable::getType(y.getIndex())==VAR){//e.g. SELECT r such that Uses(1,v)
							temp = VarConstTable::getVarList();// in vector<int> form
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Uses::isUsed(x.getIndex(),temp.at(j))==true){
										j=temp.size();
										found=true;
										resultBoolean = true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Uses(1,_); isn't it same as Uses(1,v)?
							temp = VarConstTable::getVarList();// in vector<int> form
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Uses::isUsed(x.getIndex(),temp.at(j))==true){
										j=temp.size();
										found=true;
										resultBoolean = true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
					}
				}
				else{
					if(y.getType()!=SYNONYM){//e.g. SELECT r such that Uses(x,"a")
						if(r.getIndex()==x.getIndex()){//e.g.SELECT r such that Uses(r,"a");
							for(int j=0;j<result.size();j++){
								if(Uses::isUsed(result.at(j),y.getIndex())==false){
									result.erase(result.begin()+j);
									j--;
								}
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Uses(a,"a");
							temp = StmtTable::getStmtList();
							for(int j=0;j<temp.size();j++){
								if(StmtTable::getType(temp.at(j))!=ASSIGN){
									temp.erase(temp.begin()+j);
									j--;
								}
							}
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Uses::isUsed(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Uses(s,"a");
							temp = StmtTable::getStmtList();
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Uses::isUsed(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Uses(w,"a");
							temp = StmtTable::getStmtList();
							for(int j=0;j<temp.size();j++){
								if(StmtTable::getType(temp.at(j))!=WHILE){
									temp.erase(temp.begin()+j);
									j--;
								}
							}
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Uses::isUsed(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Uses( _ ,"a"); isn't it same as Uses(s,"a")
							temp = StmtTable::getStmtList();
							found = false;
							for(int j=0;j<temp.size();j++){
								if(Uses::isUsed(temp.at(j),y.getIndex())==true){
										j=temp.size();
										found=true;
										resultBoolean=true;
									}
							}
							if(found==false){
								result.clear();
							}
						}
						/*
						else if(x.getType()=="procedure"){//this one is in CS3202
						}
						else if(x.getType()=="ifstat"){// this one is in CS3202
						}
						*/
					}
					else{
						//e.g. SELECT r such that Uses(r,v)
						if(r.getIndex()==x.getIndex()){
							for(int j=0;j<result.size();j++){
								if(Uses::getStmUsed(result.at(j)).empty()){
									result.erase(result.begin()+j);
									j--;
								}
							}
						}
						//e.g. SELECT r such that Uses(x,r)>>>(a,r)/(s,r)/(w,r)/(_,r)
						else if(r.getIndex()==y.getIndex() ){
							//e.g. r = {a,b,c}, a = {1,2,4},so check (1,a),(2,a),(3,a)...as long as one of three is true, then keep 'a'
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=ASSIGN){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Uses::isUsed(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){
								temp = StmtTable::getStmtList();
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Uses::isUsed(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=WHILE){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Uses::isUsed(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){
								temp = StmtTable::getStmtList();
								for(int j=0;j<result.size();j++){
									found = false;
									for(int k=0;k<temp.size();k++){
										if(Uses::isUsed(temp.at(k),result.at(j))==true){
											k=temp.size();
											found =true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							/*
							else if(x.getType()=="procudure"){// this one is in CS3202
							}
							else if(x.getType()=="ifstat"){// this one is in CS3202
							}
							*/
						}
						//e.g. SELECT r such that Uses(x,v)>>>(a,v)/(s,v)/(w,v)/(_,v)
						else{
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=ASSIGN){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Uses::isUsed(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){
								temp = StmtTable::getStmtList();
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Uses::isUsed(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){
								temp = StmtTable::getStmtList();
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))!=WHILE){
										temp.erase(temp.begin()+j);
										j--;
									}
								}
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Uses::isUsed(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){
								temp = StmtTable::getStmtList();
								temp2 = VarConstTable::getVarList();
								for(int j=0;j<temp2.size();j++){
									found = false;
									for(int k=0;k<temp.size();j++){
										if(Uses::isUsed(temp.at(k),temp2.at(j))==true){
											k=temp.size();
											found =true;
											resultBoolean=true;
										}
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							/*
							else if(x.getType()=="procudure"){// this one is in CS3202
							}
							else if(x.getType()=="ifstat"){// this one is in CS3202
							}
							*/
						}
					}
				}
            }
            else if(node.getType()==FOLLOWS){
				x = node.getChild().at(0);// x is the first parameter of Follows(x,y);
				y = node.getChild().at(1);
                if(x.getType()!=SYNONYM){
                    if(y.getType()!=SYNONYM){
                        //e.g. SELECT r such that Follows(1,3) ---- and Follows(1,3) will return false
                        if(Follows::isFollowsRelation(x.getIndex(),y.getIndex())==false){// no nid to care whether r is a synonym or BOOL
                            result.clear();
                        }
                    }
                    else{
                        //e.g. SELECT r such that Follows(1,y)
						if(y.getIndex() ==r.getIndex()){//e.g.SELECT r such that Follows(1,r)b
							index = Follows::getBeingFollowed(x.getIndex());
//<<<<<<< local
							/* this can be used in CS3202, because SELECT r such that Modifies (r, "x") and Follows(1,r); 
							for(int j=0;j<result.size();j++){
								if(result.at(j)!=index){
									result.erase(result.begin()+j);
									j--;
								}
							}
							*/
//							if(index!=-1){
//=======
							if(index!=-1){
//>>>>>>> other
								result.clear();
								result.push_back(index);
							}
							else {
								result.clear();
							}
						}
						else{
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Follows(1,a)
								index = Follows::getBeingFollowed(x.getIndex());
								if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
									resultBoolean = true;
								}
								else{
									result.clear();
								}		
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Follows(1,w)
								index = Follows::getBeingFollowed(x.getIndex());
								if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
									resultBoolean = true;
								}
								else{
									result.clear();
								}		
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Follows(1,s)
								index = Follows::getBeingFollowed(x.getIndex());
								if(index!=-1){
									resultBoolean = true;
								}
								else{
									result.clear();
								}		
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Follows(1,_)
								index = Follows::getBeingFollowed(x.getIndex());
								if(index!=-1){
									resultBoolean = true;
								}
								else{
									result.clear();
								}			
							}
							/*
							else if(y.getType()=="ifstat"){// this one is in CS3202
							}
							*/
						}
                    }
                }
				else{
					if(y.getType()!=SYNONYM){
						//e.g. SELECT r such that Follows(x,1)
						if(x.getIndex() ==r.getIndex()){//e.g.SELECT r such that Follows(r,1);
							index = Follows::getFollower(x.getIndex());
							if(index!=-1){
								result.clear();
								result.push_back(index);
							}
							else {
								result.clear();
							}	
						}
						else{
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Follows(a,1)
								index = Follows::getFollower(x.getIndex());
								if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
									resultBoolean = true;
								}
								else{
									result.clear();
								}		
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Follows(w,1)
								index = Follows::getFollower(x.getIndex());
								if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
									resultBoolean = true;
								}
								else{
									result.clear();
								}	
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Follows(s,1)
								index = Follows::getFollower(x.getIndex());
								if(index!=-1){
									resultBoolean = true;
								}
								else{
									result.clear();
								}	
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Follows(_,1)
								index = Follows::getFollower(x.getIndex());
								if(index!=-1){
									resultBoolean = true;
								}
								else{
									result.clear();
								}	
							}
							/*
							else if(x.getType()=="ifstat"){// this one is in CS3202
							}
							*/
						}
					}
					else{
						//e.g. SELECT r such that Follows(r,y)>>>(r,r)/(r,a)/(r,s)/(r,w)/(r,_)
						if(r.getIndex()==x.getIndex()){
							if(y.getIndex()==r.getIndex()){
								result.clear();
							}
							else if(DefinitionTable::getType(y.getIndex())==ASSIGN){
								for(int j=0;j<result.size();j++){
									index = Follows::getBeingFollowed(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){
								for(int j=0;j<result.size();j++){
									index = Follows::getBeingFollowed(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==STMT)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){
								for(int j=0;j<result.size();j++){
									index = Follows::getBeingFollowed(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
								for(int j=0;j<result.size();j++){
									index = Follows::getBeingFollowed(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==STMT)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
						}
						//e.g. SELECT r such that Follows(x,r)>>>(a,r)/(s,r)/(w,r)/(_,r)
						else if(r.getIndex()==y.getIndex()){
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){
								for(int j=0;j<result.size();j++){
									index = Follows::getFollower(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){
								for(int j=0;j<result.size();j++){
									index = Follows::getFollower(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==STMT)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){
								for(int j=0;j<result.size();j++){
									index = Follows::getFollower(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
								for(int j=0;j<result.size();j++){
									index = Follows::getFollower(result.at(j));
									if((index!=-1)&&(StmtTable::getType(index)==STMT)){
										// do nothing
									}
									else{
										result.erase(result.begin()+j);
										j--;
									}		
								}
							}
						}
						//e.g. SELECT r such that Follows(x,y); SELECT BOOLEAN only occurs here
						else{
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Follows(x,y)>>>(a,a)/(a,s)/(a,w)/(a,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Follows(x,y)>>>(s,a)/(s,s)/(s,w)/(s,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Follows(x,y)>>>(w,a)/(w,s)/(w,w)/(w,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Follows(x,y)>>>(_,a)/(_,s)/(_,w)/(_,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==ASSIGN)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==WHILE)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									found = false;
									for(int j=0;j<temp.size();j++){
										index = Follows::getBeingFollowed(temp.at(j));
										if((index!=-1)&&(StmtTable::getType(index)==STMT)){
											resultBoolean = true;
											j = temp.size();
											found = true;
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
						}
					}
				}	
            }
			else if(node.getType()==FOLLOWST){
				x = node.getChild().at(0);// x is the first parameter of Follows(x,y);
				y = node.getChild().at(1);
                if(x.getType()!=SYNONYM){
                    if(y.getType()!=SYNONYM){//e.g. SELECT r such that Follows*(1,3)
                        if(Follows::isFollowsStarRelation(x.getIndex(),y.getIndex())==false){// no nid to care whether r is a synonym or BOOL
                            result.clear();
                        }
					}
					else{
                        //e.g. SELECT r such that Follows*(1,y)
						if(y.getIndex() ==r.getIndex()){//e.g.SELECT r such that Follows*(1,r)
							result.clear();
							result =  Follows::getBeingFollowedStar(x.getIndex());
						}
						else{//e.g. SELECT r such that Follows*(1,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Follows*(1,a)
								temp = Follows::getBeingFollowedStar(x.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==ASSIGN){
										j=temp.size();
										resultBoolean=true;
										found = true;
									}
								}
								if(found==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Follows*(1,s)
								temp = Follows::getBeingFollowedStar(x.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==STMT){
										j=temp.size();
										resultBoolean=true;
										found=true;
									}
								}
								if(found==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Follows*(1,w)
								temp = Follows::getBeingFollowedStar(x.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==WHILE){
										j=temp.size();
										resultBoolean=true;
										found = true;
									}
								}
								if(found==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Follows*(1,_)
								temp = Follows::getBeingFollowedStar(x.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==WILDCARD){
										j=temp.size();
										resultBoolean=true;
										found = true;
									}
								}
								if(found==false){
									result.clear();
								}
							}
						}
					}
				}
				else{
                    if(y.getType()!=SYNONYM){
                        //e.g. SELECT r such that Follows*(x,1)
						if(x.getIndex() ==r.getIndex()){//e.g.SELECT r such that Follows*(r,1)
							result.clear();
							result =  Follows::getFollowerStar(y.getIndex());
						}
						else{//e.g. SELECT r such that Follows*(x,1)
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Follows*(a,1)
								temp = Follows::getFollowerStar(y.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==ASSIGN){
										j=temp.size();
										resultBoolean=true;
										found = true;
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Follows*(s,1)
								temp = Follows::getFollowerStar(y.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==STMT){
										j=temp.size();
										resultBoolean=true;
										found = true;
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Follows*(w,1)
								temp = Follows::getFollowerStar(y.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==WHILE){
										j=temp.size();
										resultBoolean=true;
										found = true;
									}
								}
								if(found ==false){
									result.clear();
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Follows*(_,1)
								temp = Follows::getFollowerStar(y.getIndex());
								found = false;
								for(int j=0;j<temp.size();j++){
									if(StmtTable::getType(temp.at(j))==STMT){
										j=temp.size();
										resultBoolean=true;
										found = true;
									}
								}
								if(found ==false){
									result.clear();
								}
							}
						}
					}
					else{//e.g. SELECT r such that Follows*(x,y)
						//e.g. SELECT r such that Follows*(r,r)/(r,a)/(r,w)/(r,s)/(r,_)
						if(x.getIndex()==r.getIndex()){
							if(y.getIndex()==r.getIndex()){
								result.clear();
							}
							else if(DefinitionTable::getType(y.getIndex())==ASSIGN){
								for(int j=0;j<result.size();j++){
									temp = Follows::getBeingFollowedStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==ASSIGN){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){
								for(int j=0;j<result.size();j++){
									temp = Follows::getBeingFollowedStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==WHILE){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){
								for(int j=0;j<result.size();j++){
									temp = Follows::getBeingFollowedStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==STMT){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
								for(int j=0;j<result.size();j++){
									temp = Follows::getBeingFollowedStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==STMT){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
						}
						//e.g. SELECT r such that Follows*(a,r)/(w,r)/(s,r)/(_,r)
						else if(y.getIndex()==r.getIndex()){
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){
								for(int j=0;j<result.size();j++){
									temp = Follows::getFollowerStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==ASSIGN){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){
								for(int j=0;j<result.size();j++){
									temp = Follows::getFollowerStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==WHILE){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){
								for(int j=0;j<result.size();j++){
									temp = Follows::getFollowerStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==STMT){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){
								for(int j=0;j<result.size();j++){
									temp = Follows::getFollowerStar(result.at(j));
									found = false;
									for(int k=0;k<temp.size();k++){
										if(StmtTable::getType(temp.at(k))==STMT){
											k=temp.size();
											found = true;
										}
									}
									if(found==false){
										result.erase(result.begin()+j);
										j--;
									}
								}
							}
						}
					
						else{
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){	//e.g. SELECT r such that Follows*(a,a)/(a,w)/(a,s)/(a,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==ASSIGN){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==WHILE){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=ASSIGN){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Follows*(w,a)/(w,w)/(w,s)/(w,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==ASSIGN){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==WHILE){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										if(StmtTable::getType(temp.at(j))!=WHILE){
											temp.erase(temp.begin()+j);
											j--;
										}
									}
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Follows*(s,a)/(s,w)/(s,s)/(s,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==ASSIGN){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==WHILE){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Follows*(_,a)/(_,w)/(_,s)/(_,_)
								if(DefinitionTable::getType(y.getIndex())==ASSIGN){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==ASSIGN){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WHILE){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==WHILE){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==STMT){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
								else if(DefinitionTable::getType(y.getIndex())==WILDCARD){
									temp = StmtTable::getStmtList();
									for(int j=0;j<temp.size();j++){
										temp2 = Follows::getBeingFollowedStar(temp.at(j));
										found = false;
										for(int k=0;k<temp2.size();k++){
											if(StmtTable::getType(temp2.at(k))==STMT){
												k=temp2.size();
												found = true;
												resultBoolean = true;
											}
										}
										if(found==true){
											j=temp.size();
										}
									}
									if(found==false){
										result.clear();
									}
								}
							}
						}
					}
				}
			}
//<<<<<<< local
            else if(node.getType()==PARENT){
				x = node.getChild().at(0);// x is the first parameter of Parent(x,y);
				y = node.getChild().at(1);
				if(x.getType()!=SYNONYM){
					if(y.getType()!=SYNONYM){// e.g. SELECT r such that Parent(1,3)
						if(Parent::isParentRelation(x.getIndex(),y.getIndex())==false){
							result.clear();
							resultBoolean = false;
						}
					}
					else{//e.g. SELECT r such that Parent(1,y)
						if(y.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent (1,r)
							for(int j=0;j<result.size();j++){
								index = Parent::getParent(result.at(j));
								if(index!=x.getIndex()){
									//result.erase(result.at(j));
									j--;
								}
							}
						}
						else if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(1,a)
							temp = Parent::getChild(x.getIndex());
							found = false;
							for(int j=0;j<temp.size();j++){
								if(StmtTable::getType(temp.at(j))==ASSIGN){
									found = true;
									j=temp.size();
								}
							}
							if(found ==false){
								result.clear();
								resultBoolean = false;
							}
						}
						else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent(1,w)
						}
						else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent(1,s)
						}
						else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(1,_)
						}
					}
				}
				else{
					if(y.getType()!=SYNONYM){// e.g. SELECT r such that Parent(x,2)
						if(x.getIndex()==r.getIndex()){// e.g. SELECT r such that Parent (r,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==ASSIGN){// e.g. SELECT r such that Parent (a,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==WHILE){// e.g. SELECT r such that Parent (w,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==STMT){// e.g. SELECT r such that Parent (s,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==WILDCARD){// e.g. SELECT r such that Parent (_,2)
						}
					}
					else{//e.g. SELECT r such that Parent (x,y)
						if(x.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent(r,y)
							if(y.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent(r,r)
							}
							else if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(r,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent(r,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent(r,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(r,_)
							}
						}
						else if(y.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent(x,r)
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(a,r)

							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Parent(w,r)
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Parent(s,r)
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(_,r)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(a,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(a,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent(a,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent(a,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(a,_)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Parent(w,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(w,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent(w,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent(w,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(w,_)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Parent(s,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(s,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent(s,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent(s,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(s,_)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(_,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent(_,y)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent(_,y)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent(_,y)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent(_,y)
							}
						}
					}
				}
			}
			else if(node.getType()==PARENTT){
				x = node.getChild().at(0);// x is the first parameter of Parent*(x,y);
				y = node.getChild().at(1);
				if(x.getType()!=SYNONYM){
					if(y.getType()!=SYNONYM){// e.g. SELECT r such that Parent*(1,3)

					}
					else{//e.g. SELECT r such that Parent(1,y)
						if(y.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent*(1,r)
						}
						else if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(1,a)
						}
						else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent*(1,w)
						}
						else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent*(1,s)
						}
						else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(1,_)
						}
					}
				}
				else{
					if(y.getType()!=SYNONYM){// e.g. SELECT r such that Parent*(x,2)
						if(x.getIndex()==r.getIndex()){// e.g. SELECT r such that Parent*(r,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==ASSIGN){// e.g. SELECT r such that Parent*(a,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==WHILE){// e.g. SELECT r such that Parent*(w,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==STMT){// e.g. SELECT r such that Parent*(s,2)
						}
						else if(DefinitionTable::getType(x.getIndex())==WILDCARD){// e.g. SELECT r such that Parent*(_,2)
						}
					}
					else{//e.g. SELECT r such that Parent (x,y)
						if(x.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent*(r,y)
							if(y.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent*(r,r)
							}
							else if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(r,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent*(r,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent*(r,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(r,_)
							}
						}
						else if(y.getIndex()==r.getIndex()){//e.g. SELECT r such that Parent*(x,r)
							if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(a,r)

							}
							else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Parent*(w,r)
							}
							else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Parent*(s,r)
							}
							else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(_,r)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(a,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(a,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent*(a,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent*(a,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(a,_)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WHILE){//e.g. SELECT r such that Parent*(w,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(w,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent*(w,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent*(w,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(w,_)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==STMT){//e.g. SELECT r such that Parent*(s,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(s,a)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent*(s,w)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent*(s,s)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(s,_)
							}
						}
						else if(DefinitionTable::getType(x.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(_,y)
							if(DefinitionTable::getType(y.getIndex())==ASSIGN){//e.g. SELECT r such that Parent*(_,y)
							}
							else if(DefinitionTable::getType(y.getIndex())==WHILE){//e.g. SELECT r such that Parent*(_,y)
							}
							else if(DefinitionTable::getType(y.getIndex())==STMT){//e.g. SELECT r such that Parent*(_,y)
							}
							else if(DefinitionTable::getType(y.getIndex())==WILDCARD){//e.g. SELECT r such that Parent*(_,y)
							}
						}
					}
				}
			}

    }
//=======
            else if(node.getType()==PARENT){
				;
			}
		}
	}
//>>>>>>> other

vector<int> QueryEvaluator::getResult(){
    return result;
}

bool QueryEvaluator::getResultBoolean(){
	return resultBoolean;
}

string QueryEvaluator::getResultType(){
	return resultType;
}

